﻿using HardcoreGame.Common.Configs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using Terraria;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;
using tModPorter;
namespace HardcoreGame.Common.Systems
{
    public class SunMoonSystem : ModSystem
    {
        public const int Sunrise = 13500;
        public const int SunSet1 = 37800;
        public const int SunSet2 = 45900;
        public const int Midnight = 16200;
        public const int NightIntoFade = 1800;
        public override void Load()
        {
            On_Main.DrawSunAndMoon += Change;
        }
        public static byte SafeChange(byte value, float mod)
        {
            return (byte)Math.Clamp(value * mod, 0f, 255f);
        }
        public override void ModifySunLightColor(ref Color tileColor, ref Color backgroundColor)
        {
            float GeneralMod = 0.08f * RedSun(allDay: true) * 3;
            float Extra = 0.11f * RedSun() * 3;
            tileColor.R = SafeChange(tileColor.R, 1f + GeneralMod + Extra);
            tileColor.G = SafeChange(tileColor.G, 1f - GeneralMod);
            tileColor.B = SafeChange(tileColor.B, 1f - GeneralMod);
            backgroundColor.R = SafeChange(backgroundColor.R, 1f + GeneralMod + Extra);
            backgroundColor.G = SafeChange(backgroundColor.G, 1f - GeneralMod);
            backgroundColor.B = SafeChange(backgroundColor.B, 1f - GeneralMod);
        }
        public static float RedSun(bool allDay = false)
        {
            if (Main.dayTime && (Main.time > 44900.0 || Main.time < 11500.0 || allDay))
            {
                return 1f;
            }
            if (!Main.dayTime)
            {
                if (Main.time <= 1800.0)
                {
                    return (float)Utils.GetLerpValue(1800.0, 0.0, Main.time, true);
                }
                if (Main.time >= 30600.0)
                {
                    return (float)Utils.GetLerpValue(30600.0, 32400.0, Main.time, true);
                }
            }
            return 0f;
        }
        private void Change(On_Main.orig_DrawSunAndMoon orig, Main self, Main.SceneArea sceneArea, Color moonColor, Color sunColor, float tempMushroomInfluence)
        {
          
            Texture2D sunTex = TextureAssets.Sun.Value;
            int moonWorldType = Main.moonType;
            if (!TextureAssets.Moon.IndexInRange(moonWorldType))
            {
                moonWorldType = Utils.Clamp(moonWorldType, 0, 8);
            }
            Texture2D moonTex = TextureAssets.Moon[moonWorldType].Value;
            if (Main.gameMenu)
            {
                ModMenu currentMenu = MenuLoader.CurrentMenu;
                sunTex = currentMenu.SunTexture?.Value ?? sunTex;
                moonTex = currentMenu.MoonTexture?.Value ?? moonTex;
            }
            int bgTopY = sceneArea.bgTopY;
            int sunX = (int)((54000.0 - Main.time) / 54000.0 * (double)(sceneArea.totalWidth + sunTex.Width * 2)) - sunTex.Width;
            int sunY = 0;
            float sunScale = 1f;
            float sunRot = (float)((54000.0 - Main.time) / 54000.0) * 2f - 7.3f;
            int moonX = Main.dayTime ? (int)((32400.0 - Main.time + 54000.0) / 32400.0 * (double)(sceneArea.totalWidth + moonTex.Width * 2)) - moonTex.Width : (int)((32400.0 - Main.time) / 32400.0 * (double)(sceneArea.totalWidth + moonTex.Width * 2)) - moonTex.Width;
            int MoonAdjustmentX = MoonX();
            moonX += MoonAdjustmentX;
            int MoonAdjustmentY = MoonY();
            int moonY = 0;
            float moonScale = 1f;
            float moonRot = Main.dayTime ? (float)((32400.0 - Main.time + 54000.0) / 32400.0) * 2f - 7.3f : (float)((32400.0 - Main.time) / 32400.0) * 2f - 7.3f;
            if (Main.dayTime)
            {
                double sunYHelper;
                if (Main.time < 27000.0)
                {
                    sunYHelper = Math.Pow(1.0 - (54000.0 - Main.time) / 54000.0 * 2.0, 2.0);
                    sunY = (int)(bgTopY + sunYHelper * 250.0 + 180.0);
                }
                else
                {
                    sunYHelper = Math.Pow(((54000.0 - Main.time) / 54000.0 - 0.5) * 2.0, 2.0);
                    sunY = (int)(bgTopY + sunYHelper * 250.0 + 180.0);
                }
                sunScale = (float)(1.2 - sunYHelper * 0.4);
            }
            if (!Main.dayTime)
            {
                double moonYHelper;
                if (Main.time < 16200.0)
                {
                    moonYHelper = Math.Pow(1.0 - (32400.0 - Main.time) / 32400.0 * 2.0, 2.0);
                    moonY = (int)(bgTopY + moonYHelper * 250.0 + 180.0) + MoonAdjustmentY;
                }
                else
                {
                    moonYHelper = Math.Pow(((32400.0 - Main.time) / 32400.0 - 0.5) * 2.0, 2.0);
                    moonY = (int)(bgTopY + moonYHelper * 250.0 + 180.0) + MoonAdjustmentY;
                }
                moonScale = (float)(1.2 - moonYHelper * 0.4);
                if (EventSystem.activeEvents.Contains(4))
                {
                    moonScale *= 8f;
                    moonY += 50;
                }
            }
            if (Main.dayTime)
            {
                double moonYHelper2;
                if (Main.time < 16200.0)
                {
                    moonYHelper2 = Math.Pow(1.0 - (32400.0 - Main.time + 54000.0) / 32400.0 * 2.0, 2.0);
                    moonY = (int)(bgTopY + moonYHelper2 * 250.0 + 180.0) + MoonAdjustmentY;
                }
                else
                {
                    moonYHelper2 = Math.Pow(((32400.0 - Main.time + 54000.0) / 32400.0 - 0.5) * 2.0, 2.0);
                    moonY = (int)(bgTopY + moonYHelper2 * 250.0 + 180.0) + MoonAdjustmentY;
                }
                moonScale = (float)(1.2 - moonYHelper2 * 0.4);
            }
            sunScale *= Main.ForcedMinimumZoom;
            moonScale *= Main.ForcedMinimumZoom;
            if (Main.starGame)
            {
                if (WorldGen.generatingWorld)
                {
                    Main.alreadyGrabbingSunOrMoon = true;
                    if (Main.rand.NextBool(60))
                    {
                        for (int i = 0; i < Main.numStars; i++)
                        {
                            if (Main.star[i].hidden)
                            {
                                Star.SpawnStars(i);
                            }
                        }
                    }
                    if (Main.dayTime)
                    {
                        Main.dayTime = false;
                        Main.time = 0.0;
                    }
                }
                else
                {
                    Main.starGame = false;
                }
            }
            else
            {
                Main.starsHit = 0;
            }
            if (Main.dayTime)
            {
                if ((!Main.remixWorld || Main.gameMenu) && !WorldGen.remixWorldGen)
                {
                    sunScale *= 1.1f;
                    float num4 = 1f - tempMushroomInfluence;
                    num4 -= Main.cloudAlpha * 1.5f * Main.atmo;
                    if (num4 < 0f)
                    {
                        num4 = 0f;
                    }
                    Color color = new((byte)(255f * num4), (byte)(sunColor.G * num4), (byte)(sunColor.B * num4), (byte)(255f * num4));
                    Color color2 = new((byte)(sunColor.R * num4), (byte)(sunColor.G * num4), (byte)(sunColor.B * num4), (byte)(sunColor.B * num4));
                    bool flag = false;
                    if (Main.eclipse)
                    {
                        sunTex = TextureAssets.Sun3.Value;
                        flag = true;
                    }
                    else if (!Main.gameMenu && Main.player[Main.myPlayer].head == 12)
                    {
                        sunTex = TextureAssets.Sun2.Value;
                        flag = true;
                    }
                    if (flag)
                    {
                        color2 = new((byte)(sunColor.R * num4), (byte)(sunColor.G * num4), (byte)(sunColor.B * num4), (byte)((sunColor.B - 60) * num4));
                    }
                    Vector2 origin = sunTex.Size() / 2f;
                    Vector2 sunPos = new Vector2(sunX, sunY + Main.sunModY) + sceneArea.SceneLocalScreenPositionOffset;
                    Main.spriteBatch.Draw(sunTex, sunPos, null, color, sunRot, origin, sunScale, 0, 0f);
                    Main.spriteBatch.Draw(sunTex, sunPos, null, color2, sunRot, origin, sunScale, 0, 0f);
                }
                else
                {
                    return;
                }
            }
            float num5 = 1f - Main.cloudAlpha * 1.5f * Main.atmo;
            if (num5 < 0f)
            {
                num5 = 0f;
            }
            moonColor *= num5;
            Vector2 moonPos = new Vector2(moonX, moonY + Main.moonModY) + sceneArea.SceneLocalScreenPositionOffset;
            if (WorldGen.drunkWorldGen)
            {
                Main.spriteBatch.Draw(TextureAssets.SmileyMoon.Value, moonPos, (Rectangle?)new Rectangle(0, 0, TextureAssets.SmileyMoon.Width(), TextureAssets.SmileyMoon.Height()), moonColor, moonRot / 2f + (float)Math.PI, new Vector2(TextureAssets.SmileyMoon.Width() / 2, TextureAssets.SmileyMoon.Width() / 2), moonScale, 0, 0f);
            }
            else if (Main.pumpkinMoon)
            {
                Main.spriteBatch.Draw(TextureAssets.PumpkinMoon.Value, moonPos, (Rectangle?)new Rectangle(0, TextureAssets.PumpkinMoon.Width() * Main.moonPhase, TextureAssets.PumpkinMoon.Width(), TextureAssets.PumpkinMoon.Width()), moonColor, moonRot, new Vector2(TextureAssets.PumpkinMoon.Width() / 2, TextureAssets.PumpkinMoon.Width() / 2), moonScale, 0, 0f);
            }
            else if (Main.snowMoon)
            {
                Main.spriteBatch.Draw(TextureAssets.SnowMoon.Value, moonPos, (Rectangle?)new Rectangle(0, TextureAssets.SnowMoon.Width() * Main.moonPhase, TextureAssets.SnowMoon.Width(), TextureAssets.SnowMoon.Width()), moonColor, moonRot, new Vector2(TextureAssets.SnowMoon.Width() / 2, TextureAssets.SnowMoon.Width() / 2), moonScale, 0, 0f);
            }
            else if (moonTex != TextureAssets.Moon[moonWorldType].Value)
            {
                Main.spriteBatch.Draw(moonTex, moonPos, (Rectangle?)new Rectangle(0, 0, moonTex.Width, moonTex.Width), moonColor, moonRot, new Vector2(moonTex.Width / 2), moonScale, 0, 0f);
            }
            else
            {
                Main.spriteBatch.Draw(TextureAssets.Moon[moonWorldType].Value, moonPos, (Rectangle?)new Rectangle(0, TextureAssets.Moon[moonWorldType].Width() * Main.moonPhase, TextureAssets.Moon[moonWorldType].Width(), TextureAssets.Moon[moonWorldType].Width()), moonColor, moonRot, new Vector2(TextureAssets.Moon[moonWorldType].Width() / 2, TextureAssets.Moon[moonWorldType].Width() / 2), moonScale, 0, 0f);
            }
            Rectangle celestialRec = !Main.dayTime ? new Rectangle((int)(moonX - TextureAssets.Moon[moonWorldType].Width() * 0.5 * (double)moonScale), (int)(moonY - TextureAssets.Moon[moonWorldType].Width() * 0.5 * (double)moonScale + Main.moonModY), (int)(TextureAssets.Moon[moonWorldType].Width() * moonScale), (int)(TextureAssets.Moon[moonWorldType].Width() * moonScale)) : new Rectangle((int)(sunX - TextureAssets.Sun.Width() * 0.5 * (double)sunScale), (int)(sunY - TextureAssets.Sun.Height() * 0.5 * (double)sunScale + Main.sunModY), (int)(TextureAssets.Sun.Width() * sunScale), (int)(TextureAssets.Sun.Width() * sunScale));
            ((Rectangle)celestialRec).Offset((int)sceneArea.SceneLocalScreenPositionOffset.X, (int)sceneArea.SceneLocalScreenPositionOffset.Y);
            Rectangle rectangle = new(Main.mouseX, Main.mouseY, 1, 1);
            Main.sunModY = (short)(Main.sunModY * 0.999);
            Main.moonModY = (short)(Main.moonModY * 0.999);
            if (Main.gameMenu && Main.netMode != NetmodeID.MultiplayerClient)
            {
                if (((Rectangle)rectangle).Intersects(celestialRec) || Main.alreadyGrabbingSunOrMoon)
                {
                    Main.player[Main.myPlayer].mouseInterface = true;
                }
                if ((Main.mouseLeft || Main.starGame) && Main.hasFocus)
                {
                    if (((Rectangle)rectangle).Intersects(celestialRec) || Main.alreadyGrabbingSunOrMoon)
                    {
                        if (Main.dayTime)
                        {
                            Main.time = 54000.0 * (double)((-Main.mouseX + Main.screenWidth + TextureAssets.Sun.Width()) / (Main.screenWidth + (float)(TextureAssets.Sun.Width() * 2)));
                            Main.sunModY = (short)(Main.mouseY - sunY);
                            if (Main.time > 53990.0)
                            {
                                Main.time = 53990.0;
                            }
                        }
                        else
                        {
                            Main.time = 32400.0 * (double)((-Main.mouseX + Main.screenWidth + MoonAdjustmentX + TextureAssets.Moon[moonWorldType].Width()) / (Main.screenWidth + (float)(TextureAssets.Moon[moonWorldType].Width() * 2)));
                            Main.moonModY = (short)(Main.mouseY - moonY);
                            if (Main.time > 32390.0)
                            {
                                Main.time = 32390.0;
                            }
                        }
                        if (Main.time < 10.0)
                        {
                            Main.time = 10.0;
                        }
                        Main.alreadyGrabbingSunOrMoon = true;
                    }
                }
                else
                {
                    Main.alreadyGrabbingSunOrMoon = false;
                }
            }
        }

        public override void Unload()
        {
            On_Main.DrawSunAndMoon -= Change;
        }
        public static int MoonX()
        {
            return Main.moonPhase switch
            {
                0 => 20,
                1 => -130,
                7 => -130,
                2 => -260,
                6 => -260,
                3 => -390,
                5 => -390,
                4 => -390,
                _ => 0,
            };
        }
        public static int MoonY()
        {
            return Main.moonPhase switch
            {
                0 => -20,
                1 => 30,
                7 => 30,
                2 => 60,
                6 => 60,
                3 => 90,
                5 => 90,
                4 => 90,
                _ => 0,
            };
        }
    }
}